using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using WMEncoderLib;
using Microsoft.Win32;
using System.IO;

namespace WMVConvert
{
	public class VideoPreset
	{
		private string name;

		private VideoPreset(string name)
		{
			this.name = name;
		}

		private const int NullValue = -128;
		private const string VideoRegistry = @"Software\Microsoft\Scrunch\WMVideo";

		private void SetValue(string keyName,int value)
		{
			if (value != NullValue)
			{
				using (RegistryKey key = Registry.CurrentUser.OpenSubKey(VideoRegistry,true))
				{
					key.SetValue(keyName, value, RegistryValueKind.DWord);
				}
			}
		}

		public void Set()
		{
			CleanSettings();
			SetValue("NumBFrames", this.videoBFrameDist);
			SetValue("Lookahead", this.videoLookahead);
			SetValue("Force LoopFilter", this.videoLoopfilter);
			SetValue("Motion Match Method", this.videoMMatch);
			SetValue("Motion Search Level", this.videoMSLevel);
			SetValue("Motion Search Range", this.videoMSRange);
			SetValue("Force Overlap", this.videoOverlap);
		}

		public static void CleanSettings()
		{
			try
			{
				Registry.CurrentUser.DeleteSubKeyTree(VideoRegistry);
			}
			catch
			{
			}
			Registry.CurrentUser.CreateSubKey(VideoRegistry);
		}

		public string Name
		{
			get { return name; }
		}

		private WMENC_VIDEOCOMPLEXITY videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_DEFAULT_COMPLEXITY;
		public WMENC_VIDEOCOMPLEXITY VideoPerformance
		{
			get { return videoPerformance; }
		}

		private int videoLookahead = NullValue;
		public int VideoLookahead
		{
			get { return videoLookahead; }
		}

		private int videoLoopfilter = NullValue;
		public int VideoLoopfilter
		{
			get { return videoLoopfilter; }
		}

		private int videoOverlap = NullValue;
		public int VideoOverlap
		{
			get { return videoOverlap; }
		}

		private int videoMSLevel = NullValue;
		public int VideoMSLevel
		{
			get { return videoMSLevel; }
		}

		private int videoBFrameDist = NullValue;
		public int VideoBFrameDist
		{
			get { return videoBFrameDist; }
		}

		private int videoMSRange = NullValue;
		public int VideoMSRange
		{
			get { return videoMSRange; }
		}

		private int videoMMatch = NullValue;
		public int VideoMMatch
		{
			get { return videoMMatch; }
		}

		private static readonly VideoPreset fast = new VideoPreset("Fast");
		public static VideoPreset Fast
		{
			get
			{
				fast.videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL40;
				fast.videoLookahead = 16;
				fast.videoLoopfilter = 1;
				fast.videoOverlap = 1;
				fast.videoMSLevel = 3;
				return fast;
			}
		}

		private static readonly VideoPreset good = new VideoPreset("Good");
		public static VideoPreset Good
		{
			get
			{
				good.videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL60;
				good.videoLookahead = 16;
				good.videoLoopfilter = 1;
				good.videoMSLevel = 3;
				return good;
			}
		}

		private static readonly VideoPreset better = new VideoPreset("Better");
		public static VideoPreset Better
		{
			get
			{
				better.videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL60;
				better.videoLookahead = 16;
				better.videoLoopfilter = 1;
				better.videoBFrameDist = 1;
				better.videoMSLevel = 4;
				better.videoMSRange = -1;
				return better;
			}
		}

		private static readonly VideoPreset best = new VideoPreset("Best");
		public static VideoPreset Best
		{
			get
			{
				best.videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL80;
				best.videoLookahead = 16;
				best.videoLoopfilter = 1;
				best.videoBFrameDist = 1;
				best.videoMSLevel = 1;
				best.videoMSRange = -1;
				best.videoMMatch = -1;
				return best;
			}
		}

		private static readonly VideoPreset insane = new VideoPreset("Insane");
		public static VideoPreset Insane
		{
			get
			{
				insane.videoPerformance = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL80;
				insane.videoLookahead = 16;
				insane.videoLoopfilter = 1;
				insane.videoBFrameDist = 1;
				insane.videoMSLevel = 2;
				insane.videoMSRange = -1;
				insane.videoMMatch = 1;
				return insane;
			}
		}

		public static VideoPreset GetPreset(string name)
		{
			PropertyInfo propInfo = typeof(VideoPreset).GetProperty(name, BindingFlags.Static|BindingFlags.Public|BindingFlags.GetProperty);
			return (VideoPreset)propInfo.GetValue(null,null);
		}
	}

}
